/**
 * @file   Property.cpp
 * @author Djuro Drljaca (djurodrljaca@gmail.com)
 * @date   2014-04-29
 * @brief  DON property object.
 *
 * Copyright 2014  Djuro Drljaca (djurodrljaca@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <DON/Core/Node/Property.h>

using namespace DON::Core::Node;
using namespace DON::Core::DataType;

class Property::Private
{
public:
    Private()
        : propertyId(0u),
          accessModifier(AccessModifier_Invalid),
          name(),
          value(NULL)
    { }

    ~Private()
    {
        delete value;
    }

    quint16 propertyId;
    AccessModifier accessModifier;
    QString name;
    AbstractDataType *value;
};

Property::Property()
    : d(new Private())
{
}

Property::Property(const quint16 propertyId,
                   const AccessModifier accessModifier,
                   const QString &name,
                   const AbstractDataType *value)
    : d(new Private())
{
    d->propertyId = propertyId;
    d->accessModifier = accessModifier;
    d->name = name;

    if (value != NULL)
    {
        d->value = value->clone();
    }
}

Property::Property(const Property &other)
    : d(new Private())
{
    d->propertyId = other.d->propertyId;
    d->accessModifier = other.d->accessModifier;
    d->name = other.d->name;

    if (other.d->value != NULL)
    {
        d->value = other.d->value->clone();
    }
}

Property & Property::operator=(const Property &other)
{
    d->propertyId = other.d->propertyId;
    d->accessModifier = other.d->accessModifier;
    d->name = other.d->name;

    setValue(other.d->value);

    return *this;
}

Property::~Property()
{
    delete d;
}

bool Property::isValid() const
{
    const bool valid = isAccessModifierValid(d->accessModifier) && isDataTypeValid(getDataType());

    return valid;
}

quint16 Property::getId() const
{
    return d->propertyId;
}

void Property::setId(const quint16 propertyId)
{
    d->propertyId = propertyId;
}

DataType Property::getDataType() const
{
    DataType::DataType dataType = DataType_Invalid;

    if (d->value != NULL)
    {
        dataType = d->value->getDataType();
    }

    return dataType;
}

AccessModifier Property::getAccessModifier() const
{
    return d->accessModifier;
}

bool Property::setAccessModifier(const AccessModifier accessModifier)
{
    bool success = false;

    if (isAccessModifierValid(accessModifier))
    {
        d->accessModifier = accessModifier;
        success = true;
    }

    return success;
}

QString Property::getName() const
{
    return d->name;
}

void Property::setName(const QString &name)
{
    d->name = name;
}

const AbstractDataType * Property::getValue() const
{
    return d->value;
}

void Property::setValue(const AbstractDataType * value)
{
    delete d->value;
    d->value = NULL;

    if (value != NULL)
    {
        d->value = value->clone();
    }
}
